package com.modules.service.sys.impl;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.constant.CommonConstant;
import com.common.constant.LoggerConstant;
import com.common.listener.MyServletContextListener;
import com.common.util.AES2;
import com.common.util.AesMin;
import com.common.util.ImageUtil;
import com.common.util.MyDateUtil;
import com.common.vo.LoginUser;
import com.common.vo.Result;
import com.modules.dao.sys.MenuDao;
import com.modules.dao.sys.UserDao;
import com.modules.dto.sys.req.UserEntityReq;
import com.modules.dto.sys.resp.MenuDtoResp;
import com.modules.dto.sys.resp.UserEntityResp;
import com.modules.entity.sys.UserEntity;
import com.modules.service.sys.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * service用户
 *
 * @author yyq
 */
@Service
public class UserServiceImp extends ServiceImpl<UserDao, UserEntity> implements UserService{

    private final Logger logger = LoggerFactory.getLogger(UserServiceImp.class);

    @Autowired
    private MenuDao mdao;
    @Autowired
    private HttpSession session;


    /**
     * 查询
     * @return
     */
    public Result<?> select(UserEntityReq entity) {
        entity.setDelFlag(CommonConstant.ZERO);
        List<UserEntityResp> list = baseMapper.select(entity);
        Integer count = baseMapper.selectCount(entity);
        return Result.page(list, Long.valueOf(count));
    }

    /**
     * 插入
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Result<?> insert(UserEntity user) {
    	return insertOrupdate(user);
    }

    /**
     * 更新
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Result<?> update(UserEntity entity) {
        Result<?> result = insertOrupdate(entity);
        LoginUser u = (LoginUser) session.getAttribute(CommonConstant.LOGIN_USER);
        if(entity.getId() == u.getId()) {
            u.setImg(entity.getImg());
            session.setAttribute(CommonConstant.LOGIN_USER, u);
        }
        return result;
    }

    public Result<?> insertOrupdate(UserEntity user){
        UserEntity u = baseMapper.existsData(user);
        if (u != null) {
            return Result.fail("当前登录名已被占用，请更改");
        }
        String s = "";
		try {
			s = AES2.Encrypt(CommonConstant.DEFAULT_PASS, AES2.CODE);
		} catch (Exception e) {
			e.printStackTrace();
			return Result.fail("密码转换异常："+e.getMessage());
		}
        user.setPassword(s);
        Result result = null;
        if (user.getId() == null) {
            baseMapper.insert(user);
            result =  Result.success(Result.ADD_MSG);
        } else {
            baseMapper.updateById(user);
            result = Result.success(Result.UPDATE_MSG);
        }
        // 把临时文件保存为正式
        if (StrUtil.isNotEmpty(user.getImg())) {
            String date = MyDateUtil.getStrCurrentDate(MyDateUtil.sfh_ymd);
            String arr [] = date.split("-");
            String savePath = "upload/" + user.getLastOid() + "/photo/jzjz/" + (arr[0] +"-"+ arr[1]) + "/"+arr[2];
            String fileMove = ImageUtil.saveFileRename(user.getImg(), savePath, ImageUtil.NGINXPATH, null, "upload/" + user.getLastOid() + "/temp");
            user.setImg(fileMove);// 存储路径
            baseMapper.updateById(user);
        }
        return result;
    }

    /**
     * 登录
     * @return
     */
    public Result<?> selectLogin(UserEntity user) {
        try {
            /*Result result = codeCheck();
            if (!result.getSuccess()){
                return result;
            }*/
            // 当前用户失败 5 次后限制
            Long ipTime = (Long) MyServletContextListener.loginMap.get(user.getUserName()+"_time");
            if(ipTime != null) {
                long tempTime = MyDateUtil.getDateMinute(ipTime);
                if(tempTime < 5) {
                    return Result.fail("当前用户验证失败次数过多，请"+(5-tempTime)+"分钟后再操作");
                }else {
                    MyServletContextListener.loginMap.remove(user.getUserName()+"_time");
                }
            }
            user.setUserName(AesMin.aesDecrypt(user.getUserName()));// 前端解密
            user.setPassword(AesMin.aesDecrypt(user.getPassword()));// 前端解密
            String s = AES2.Encrypt(user.getPassword(), AES2.CODE);// 后端加密
            user.setPassword(s);
            user.setDelFlag(CommonConstant.ZERO);
            UserEntityResp login = baseMapper.selectLogin(user);
            if (login != null) {
                if (MyDateUtil.getDateCount(null, login.getUseDate(), MyDateUtil.sfh_ymd) < MyDateUtil.getDate().getTime()) {
                    if(ipTime == null) {
                        MyServletContextListener.loginMap.put(user.getUserName()+"_time", System.currentTimeMillis());
                    }
                    return Result.fail("您的使用期限已过期");
                }
                if (login.getOrgState() == CommonConstant.ZERO) {
                    if(ipTime == null) {
                        MyServletContextListener.loginMap.put(user.getUserName()+"_time", System.currentTimeMillis());
                    }
                    return Result.fail("当前机构已停用");
                }
                if (login.getRoleState() == CommonConstant.ZERO) {
                    if(ipTime == null) {
                        MyServletContextListener.loginMap.put(user.getUserName()+"_time", System.currentTimeMillis());
                    }
                    return Result.fail("当前角色已停用");
                }
                LoginUser loginUser = new LoginUser();
                BeanUtils.copyProperties(login, loginUser);// 复制对象值
                session.setAttribute(CommonConstant.LOGIN_USER, loginUser);
                String theme = StrUtil.isBlank(login.getTheme())?"theme1":login.getTheme();
                session.setAttribute("theme", theme);
                session.setAttribute("cache", login.getCache());
                session.setAttribute("themeStyle", login.getThemeStyle());
                String module = "module_theme0";
                if(StrUtil.isNotBlank(login.getThemeStyle())) {
                	if(login.getThemeStyle().indexOf("module1") != -1) {
                		module = "module_"+theme;
                	}
                }
                session.setAttribute("moduleTheme", module);
                session.setAttribute("suoPing", "ok");
                session.setMaxInactiveInterval(60*60);// 单位为秒 这里设置了一个钟（session存活时间）
                // 获取菜单按钮权限
                List<MenuDtoResp> list = mdao.selectRoleMenuOperationLogin(login.getRid());
                session.setAttribute(CommonConstant.POWER_LIST, list);
                return Result.success("登录成功");
            } else {
                if(ipTime == null) {
                    MyServletContextListener.loginMap.put(user.getUserName()+"_time", System.currentTimeMillis());
                }
                return Result.fail("账号/密码错误，登录失败");
            }
        } catch (Exception e) {
            logger.error(LoggerConstant.ERROR_MSG, e);
            return Result.error("系统异常："+e.getMessage());
        }
    }

    /**
     * 解锁
     * @return
     */
    public Result<?> suoPing(String mark, UserEntity user) {
        if (StrUtil.isEmpty(mark)) {
            session.setAttribute("suoPing", "");
            return Result.fail("锁屏中");
        }
        try {
            if (StrUtil.isEmpty(user.getPassword())) {
                return Result.fail();
            }
            // 当前用户失败 5 次后限制
            Long ipTime = (Long) MyServletContextListener.loginMap.get(user.getUserName()+"_time");
            if(ipTime != null) {
                long tempTime = MyDateUtil.getDateMinute(ipTime);
                if(tempTime < 5) {
                    return Result.fail("当前用户验证失败次数过多，请"+(5-tempTime)+"分钟后再操作");
                }else {
                    MyServletContextListener.loginMap.remove(user.getUserName()+"_time");
                    session.setAttribute("login_fail_count", 1);
                }
            }
        	user.setDelFlag(CommonConstant.ZERO);
        	user.setPassword(AesMin.aesDecrypt(user.getPassword()));// 前端解密
            String s = AES2.Encrypt(user.getPassword(), AES2.CODE);// 后端加密
            user.setPassword(s);
            UserEntityResp login = baseMapper.selectLogin(user);
            if (login != null) {
                session.setAttribute("suoPing", "ok");
                return Result.success("解锁成功");
            }else {
                Integer failCount = (Integer) session.getAttribute("login_fail_count");
                // 当前IP登录错误计算
                failCount = (failCount == null) ? 1 : failCount;
                failCount ++;
                session.setAttribute("login_fail_count", failCount);
                if(failCount != null && failCount > 5) {
                    ipTime = (Long) MyServletContextListener.loginMap.get(user.getUserName()+"_time");
                    if(ipTime == null) {
                        MyServletContextListener.loginMap.put(user.getUserName()+"_time", System.currentTimeMillis());
                    }
                }
                return Result.fail("验证失败");
            }
        } catch (Exception e) {
            logger.error(LoggerConstant.ERROR_MSG, e);
            return Result.error("系统异常："+e.getMessage());
        }
    }

    /**
     * 修改密码
     * @param id
     * @param oldPass
     * @param password1
     * @param password2
     * @return
     */
    @Override
    @Transactional
    public Result<?> updatePassWord(String id, String oldPass, String password1, String password2) {
        LoginUser loginUser = (LoginUser) session.getAttribute(CommonConstant.LOGIN_USER);
        if(!loginUser.getId().equals(id)){
            return Result.fail("修改失败，当前修改人和登录人信息不符");
        }
        if(StrUtil.isEmpty(oldPass) || StrUtil.isEmpty(password1) || StrUtil.isEmpty(password2)){
            return Result.fail("修改失败，密码不能为空");
        }
        if(!password1.equals(password2)){
            return Result.fail("修改失败，两次密码不一致");
        }
        try {
            UserEntityReq user = new UserEntityReq();
            String old = AesMin.aesDecrypt(oldPass);// 前端解密
            old = AES2.Encrypt(old, AES2.CODE);// 后端加密
            String newPass = AesMin.aesDecrypt(password2);// 前端解密
            newPass = AES2.Encrypt(newPass, AES2.CODE);// 后端加密

            // 开始根据ID和密码修改
            LambdaQueryWrapper<UserEntity> lambdaQuery = Wrappers.lambdaQuery();
            lambdaQuery.eq(UserEntity::getId, loginUser.getId());
            lambdaQuery.eq(UserEntity::getPassword, old);
            UserEntity userEntity = new UserEntity();
            userEntity.setPassword(newPass);
            int count = baseMapper.update(userEntity, lambdaQuery);
            return count > CommonConstant.ZERO ? Result.success(Result.UPDATE_MSG):Result.fail("修改失败，密码错误");
        } catch (Exception e) {
            logger.error(LoggerConstant.ERROR_MSG, e);
            return Result.error("系统异常："+e.getMessage());
        }
    }
    






}
